package org.candy.core.convert.support;

import lombok.Data;
import org.candy.core.convert.converter.Converter;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

@Data
public class Converters {

    private static Map<ConverterKey<?, ?>, Converter<?, ?>> converters;

    static {
        converters = new HashMap<>();
    }

    /**
     1 获取 Converter<S, T> 中 S 和 T 的具体类型
     2 构造 ConverterKey
     3 ConverterKey作为key，Converter作为value 添加到 converters 中
     */
    @SuppressWarnings("unchecked")
    public <S, T> void add(Converter<S, T> converter) {
        Type[] superClassType = converter.getClass().getGenericInterfaces();
        Type[] types = ((ParameterizedType)superClassType[0]).getActualTypeArguments();
        ConverterKey<S, T> converterKey = new ConverterKey<>((Class<S>) types[0], (Class<T>) types[1]);
        converters.put(converterKey, converter);
    }

    @SuppressWarnings("unchecked")
    public <S, T> T convert(S source, Class<T> targetType) {
        ConverterKey<S, T> converterKey = new ConverterKey<>((Class<S>) source.getClass(), targetType);
        Converter<S, T> converter = (Converter<S, T>) converters.get(converterKey);
        return converter.convert(source);
    }

}
